package com.ghsc.ghxc.jsb.ext.http

import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import com.cn.appcore.base.BaseViewModel
import com.cn.appcore.config.AppException
import com.cn.appcore.config.ExceptionHandle
import com.cn.appcore.ext.loge
import com.cn.appcore.ext.showToast
import com.cn.appcore.http.bean.BaseListResponse
import com.cn.appcore.http.bean.BaseResponse
import com.ghsc.ghxc.jsb.app.App
import com.ghsc.ghxc.jsb.config.LoginHelper
import com.ghsc.ghxc.jsb.utils.NetworkUtil
import kotlinx.coroutines.*

/**
 * 过滤服务器结果，失败抛异常
 * @param block 请求体方法，必须要用suspend关键字修饰
 * @param success 成功回调
 * @param error 失败回调 可不传
 */
fun <T> BaseViewModel.request(
    block: suspend () -> BaseResponse<T>,
    success: (T) -> Unit,
    error: (AppException) -> Unit = {
        showToast(it.errorMsg)
    }
){
    if (!NetworkUtil.isNetworkAvailable(App.instance)){
        //没有网络
        netWorkMsg.value = "断网了"
        errorMsg.value = "网络失败"
        return
    }
    viewModelScope.launch {
        runCatching {
            //请求体
            block()
        }.onSuccess {
            runCatching {
                //校验请求结果码是否正确，不正确会抛出异常走下面的onFailure
                executeResponse(it) { t -> success(t)
                }
            }.onFailure { e ->
                //打印错误消息
                loge(e.message?:"")
                //打印错误栈信息
                e.printStackTrace()
                //失败回调
                error(ExceptionHandle.handleException(e))
            }
        }.onFailure {
            //打印错误消息
            loge(it.message?:"")
            //打印错误栈信息
            it.printStackTrace()
            //失败回调
            error(ExceptionHandle.handleException(it))
        }
    }
}

/**
 * 过滤服务器结果，失败抛异常
 * @param block 请求体方法，必须要用suspend关键字修饰
 * @param success 成功回调
 * @param error 失败回调 可不传
 */
fun <T> FragmentActivity.request(
    block: suspend () -> BaseResponse<T>,
    success: (T) -> Unit,
    onError: (Int) -> Unit = {},
    error: (AppException) -> Unit = {}
){
    if (!NetworkUtil.isNetworkAvailable(App.instance)){
        //没有网络
        showToast("网络失败")
        return
    }
    lifecycleScope.launch {
        runCatching {
            //请求体
            block()
        }.onSuccess {
            runCatching {
                //校验请求结果码是否正确，不正确会抛出异常走下面的onFailure
                coroutineScope {
                    when (it.code) {
                        LoginHelper.SUCCESS_CODE -> {
                            success(it.data)
                        }
                        LoginHelper.LOGON_FAILURE  -> {
                            LoginHelper.startLoginPage()
                        }
                        LoginHelper.HTTP_TOKEN_EXPIRED  -> {
                            LoginHelper.startLoginPage()
                        }
                        else -> {
                            showToast(it.msg)
                            onError(it.code)
                        }
                    }
                }
            }.onFailure { e ->
                //打印错误消息
                loge(e.message?:"")
                //打印错误栈信息
                e.printStackTrace()
                //失败回调
                error(ExceptionHandle.handleException(e))
            }
        }.onFailure {
            //打印错误消息
            loge(it.message?:"")
            //打印错误栈信息
            it.printStackTrace()
            //失败回调
            error(ExceptionHandle.handleException(it))
        }
    }
}

/**
 * 过滤服务器结果，失败抛异常
 * @param block 请求体方法，必须要用suspend关键字修饰
 * @param success 成功回调
 * @param error 失败回调 可不传
 */
fun <T> FragmentActivity.requestList(
    block: suspend () -> BaseListResponse<T>,
    success: (List<T>) -> Unit,
    error: (AppException) -> Unit = {
        showToast(it.errorMsg)
    }
){
    if (!NetworkUtil.isNetworkAvailable(App.instance)){
        //没有网络
        showToast("网络失败")
        return
    }
    lifecycleScope.launch {
        runCatching {
            //请求体
            block()
        }.onSuccess {
            runCatching {
                //校验请求结果码是否正确，不正确会抛出异常走下面的onFailure
                    coroutineScope {
                        when (it.code) {
                            LoginHelper.SUCCESS_CODE -> {
                                success(it.data)
                            }
                            LoginHelper.LOGON_FAILURE -> {
                                LoginHelper.startLoginPage()
                            }
                            LoginHelper.HTTP_TOKEN_EXPIRED  -> {
                                LoginHelper.startLoginPage()
                            }
                            else -> {
                                showToast(it.msg)
                            }
                        }
                    }
            }.onFailure { e ->
                //打印错误消息
                loge(e.message?:"")
                //打印错误栈信息
                e.printStackTrace()
                //失败回调
                error(ExceptionHandle.handleException(e))
            }
        }.onFailure {
            //打印错误消息
            loge(it.message?:"")
            //打印错误栈信息
            it.printStackTrace()
            //失败回调
            error(ExceptionHandle.handleException(it))
        }
    }
}


/**
 * 过滤服务器结果，失败抛异常
 * @param block 请求体方法，必须要用suspend关键字修饰
 * @param success 成功回调
 * @param error 失败回调 可不传
 */
fun <T> BaseViewModel.requestList(
    block: suspend () -> BaseListResponse<T>,
    success: (List<T>) -> Unit,
    error: (AppException) -> Unit = {}
){
    if (!NetworkUtil.isNetworkAvailable(App.instance)){
        //没有网络
        netWorkMsg.value = "断网了"
        errorMsg.value = "网络失败"
        return
    }
    viewModelScope.launch {
        runCatching {
            //请求体
            block()
        }.onSuccess {
            runCatching {
                //校验请求结果码是否正确，不正确会抛出异常走下面的onFailure
                executeListResponse(it) { t -> success(t)
                }
            }.onFailure { e ->
                //打印错误消息
                loge(e.message?:"")
                //打印错误栈信息
                e.printStackTrace()
                //失败回调
                error(ExceptionHandle.handleException(e))
            }
        }.onFailure {
            //打印错误消息
            loge(it.message?:"")
            //打印错误栈信息
            it.printStackTrace()
            //失败回调
            error(ExceptionHandle.handleException(it))
        }
    }
}


/**
 * 请求结果过滤，判断请求服务器请求结果是否成功，不成功则会抛出异常
 */
suspend fun <T> BaseViewModel.executeResponse(
    response: BaseResponse<T>,
    success: suspend CoroutineScope.(T) -> Unit
) {
    coroutineScope {
        when (response.code) {
            LoginHelper.SUCCESS_CODE -> {
                success(response.data)
            }
            LoginHelper.LOGON_FAILURE -> {
                againLoginMsg.value = response.msg
            }
            LoginHelper.HTTP_TOKEN_EXPIRED  -> {
                againLoginMsg.value = response.msg
            }
            else -> {
                throw AppException(
                    response.code,
                    response.msg,
                    response.msg
                )
//                errorMsg.value = response.msg
            }
        }
    }
}

/**
 * 请求结果过滤，判断请求服务器请求结果是否成功，不成功则会抛出异常
 */
suspend fun <T> BaseViewModel.executeListResponse(
    response: BaseListResponse<T>,
    success: suspend CoroutineScope.(List<T>) -> Unit
) {
    coroutineScope {
        when (response.code) {
            LoginHelper.SUCCESS_CODE -> {
                success(response.data)
            }
            LoginHelper.LOGON_FAILURE -> {
                againLoginMsg.value = response.msg
            }
            LoginHelper.HTTP_TOKEN_EXPIRED  -> {
                againLoginMsg.value = response.msg
            }
            else -> {
                throw AppException(
                    response.code,
                    response.msg,
                    response.msg
                )
//                errorMsg.value = response.msg
            }
        }
    }
}
